import axios from "axios";

/* 
  封装axios的需求
    1. 复用请求前缀
    2. 希望直接得到响应体数据
    3. 携带公共请求参数 token
    4. 发送请求后promise,如果变成成功状态，就是请求成功，如果变成失败状态，就是请求失败或功能失败
    5. 请求失败，自动进行错误提示
*/
/* axios.get("/api/xxx").then().catch(); */

const request = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API, //vite手架与法
  timeout: 20000,
});

/*
  所以：将来使用request发送请求
    1. 触发请求拦截器回调函数
    2. 发送请求 -> axios内部封装的，默认看不到
    3. 触发响应拦截器回调函数
    4. 走后面流程，await之后


  源码：
    promise = promise.resolve(config)

    return promise 
      .then(请求拦截器成功回调, 请求拦截器失败回调)  // 1
      .then(dispatchRequest, undefined) // 2
      .then(响应拦截器成功回调, 响应拦截器失败回调) // 3
 
    因为第一个promise是成功状态，所以第一个then方法只会触发第一个回调函数
    因为第一个promise结果值是config，所以第一个then方法得第一个回调函数的参数就是config

    then方法一定返回一个promise，
      如果内部函数报错，或者内部函数返回失败的promise， then方法返回的promise就是失败状态
      否则then方法返回的promise就是成功状态

    因为请求拦截器成功回调没有报错，也没有返回失败的promise，所以最终then方法返回promise就是成功状态
    因为第二then方法，触发成功的回调 -> dispatchRequest 发送请求

    dispatchRequest返回一个promise，看响应状态码，200-299就是成功，否则是失败
*/

// 设置拦截器
// 请求拦截器（发送请求之前触发）
request.interceptors.request.use(
  (config) => {
    //config是发送请求的配置对象
    //config.headers.Authorization = "token";
    return config;
  }
  /*  (error) => {
    return Promise.reject(error);
  } */
);
// 响应拦截器 (响应回来第一时间触发)
request.interceptors.response.use(
  // 成功的回调 200-299
  (response) => {
    //response是响应对象
    /*
      response: {
        config, // 请求配置
        headers, // 响应头
        status, // 响应状态码
        request, // xhr
        data,  // 响应体数据 ->
          {
            code: 200,
            data: xxx, // 真正需要的数据
            message: '', // 错误原因
            ok: true
          }
      }
    */

    // 判断请求是否真正成功
    // 200不是固定的值，测试后端接口，看成功返回code的值是多少来定义
    if (response.data.code === 200) {
      // 功能成功
      // return response.data
      return response.data.data;
    } else {
      // 功能失败
      return Promise.reject();
    }
  },
  // 失败的回调 非200-299
  (error) => {
    if (error.response) {
      // 服务器返回了响应，响应是失败的
      if (error.status === 401) {
        // unAuthorization token过期
        // 双token刷新机制：发送请求使用refreshToken获取新token
        // 退出登录
        // 将本地存储token删除掉（pinia、localStorage）
        // window.location.href = "/login";
        window.location.reload(); // 刷新（触发全局导航守卫，因为没有token，自动跳转到登录页面）
        return;
      } else if (error.status === 404) {
        // ElMessage.error('访问资源不存在')
      } else if (error.status === 500) {
        // ElMessage.error('请求异常，请稍后重试')
      } else {
        // ElMessage.error('请求失败，请联系管理员解决')
      }
    } else {
      // 服务器没有响应，请求在前端就已经失败了
      if (error.message.indexOf("Network Error")) {
        // 没有网
        // ElMessage.error('网络异常，请尝试重新连接网络')
      } else if (error.message.indexOf("timeout")) {
        // 请求超时
        // ElMessage.error('网络速度慢，请换一个网络试试')
      } else {
        // ElMessage.error('请求失败，请联系管理员解决')
      }
    }

    return Promise.reject();
  }
);

export default request;
